#include "gui.menu.h"

// Constructor
TOB::UIMenu::UIMenu(uint16 x, uint16 y, uint16 w, uint16 h):
  UIWindow(x, y, w, h) {
  this->y = scrollY = 0;
  selected = 0;
  drawRest = true;
}


// Destructor
TOB::UIMenu::~UIMenu() {
  for(Item *item: items) {
    delete item;
  }
  for(uint16 i = 0; i < height; ++i) {
    setCursor(0, i);
    clearLine();
  }
  dispose();
}


// New item
TOB::UIMenu::Item *TOB::UIMenu::insert(String title, 
    TOB::UIMenu::Item::Handler handler) {
  Item *item = new Item();
  item->title = title;
  item->handler = handler;
  items.push_back(item);
  return item;
}


// Set focus
void TOB::UIMenu::focus() {
  running = true;
  showCursor(false);

  while(running) {
    selected = y + scrollY;
    print();
    Char in = getChar();

    // Switch input
    switch(in) {
     // Select next
     case KEY_DOWN:
      next(); break;

     // Select previous
     case KEY_UP:
      prev(); break;

     // Select item
     case '\n':
      items[selected]->handler(); break;
    }
  }
}


// Print current state
void TOB::UIMenu::print() {
  String str;
  setCursor(0, 0);
  uint32 bound = items.size() - scrollY;
  bound = (bound >= height) ? height : bound;
  for(uint32 i = scrollY; i < bound + scrollY; ++i) {
    setColor((i == selected) ? Color::SelectedMenu : Color::Default);
    str = items[i]->title.substr(0, width);
    putString(str);
    if(drawRest) {
      for(uint32 j = 0; j < width - str.size(); ++j) {
        putChar(' ');
      }
    } else if(str.size() < width) {
      putChar('\n');
    }
  }
}


// Next item
void TOB::UIMenu::next() {
  if(selected < items.size() - 1) {
    if(y < height - 1) {
      ++y;
    } else {
      ++scrollY;
    }
  }
}


// Previous item
void TOB::UIMenu::prev() {
  if(selected) {
    if(y) {
      --y;
    } else {
      --scrollY;
    }
  }
}
